package com.googlecode.bipol.war.session;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.charless.spring.jsonrpc.JsonRpcController;

import com.googlecode.bipol.war.services.QuestionManagerImpl;
import com.googlecode.bipol.war.services.TopicManagerImpl;
import com.metaparadigm.jsonrpc.JSONRPCBridge;

/**
 * @see com.googlecode.bip.entity.IUser
 * @see com.googlecode.bip.entity.User
 */
@Deprecated // TODO: Delete this, use BipSession instead
public class _BiPolSession
    extends JsonRpcController
        implements Serializable, _IBiPolSession
{
    private static final long serialVersionUID = 4L;
    private static final transient Logger logger = Logger.getLogger( _BiPolSession.class );
    private static final String JSONRPCBridgeNAME = "JSONRPCBridge";

    /**
     * Current Session
     * <br/>
     * HttpSession attribute : {@value}
     */
    public static final String SESSION = "session";

    /** current user id - 0 no user id */
    private int userId;

    /** current user name */
    private String userName;

    /** current Locale for user */
    private Locale locale;

    /** login date */
    private Timestamp loginTimestamp;

    public _BiPolSession()
    {
        super();
    }

    protected  void registerSessionAjaxServicesImpl(JSONRPCBridge bridge) throws Exception{
        bridge.enableReferences();
        //bridge.registerCallableReference(.class);

        this.userName = getHttpServletRequest().getRemoteUser();
        logger.info("JSON Session bridge '"+bridge.toString()+"'");
        logger.info(this.toString());
        logger.info("UserName="+this.userName);

        bridge.registerObject("TopicManager", new TopicManagerImpl(),com.googlecode.bipol.war.services.TopicManager.class);
        bridge.registerObject("QuestionManager", new QuestionManagerImpl(),com.googlecode.bipol.war.services.QuestionManager.class);
        logger.info("test");
    }

    /* (non-Javadoc)
     * @see com.googlecode.bipol.war.session.IBipolSession#reset()
     */
    @Override
    public void reset()
    {
        this.userId = 0;
        this.userName = null;
        // TODO: a l'heure pret ? la journ�e ?
        Calendar c = new GregorianCalendar();
        c.set( Calendar.MILLISECOND, 0 ); // ignore milliseconds
        c.set(  Calendar.SECOND, 0 ); // ignore seconds
        c.set(  Calendar.MINUTE, 0 ); // ignore minutes
        c.set(  Calendar.HOUR, 0 ); // ignore hours ????? TODO !
        this.loginTimestamp = new Timestamp( c.getTimeInMillis() );
    }

    /**
     * Invalidate the session
     */
    public void invalidateSession() {
        HttpSession session = this.getHttpServletRequest().getSession();
        logger.info("Closing session: "+session.getId());
        session.invalidate();
    }

    /* (non-Javadoc)
     * @see com.googlecode.bipol.war.session.IBipolSession#isConnected()
     */
    @Override
    public boolean isConnected()
    {
        return getUserid() != 0;
    }

    /* (non-Javadoc)
     * @see com.googlecode.bipol.war.session.IBipolSession#checkConnection()
     * /
    @Override
    public void checkConnection() throws NotConnectedException
    {
        if( ! isConnected() ) {
            throw new NotConnectedException();
            }
    }*/
/*
    // TO DO
    / * (non-Javadoc)
     * @see com.googlecode.bipol.war.session.IBipolSession#checkReferentConnection()
     * /
    @Override
    public void checkReferentConnection() throws NotConnectedException
    {
        // TO DO
    }
*/
    // TO DO
    /* (non-Javadoc)
     * @see com.googlecode.bipol.war.session.IBipolSession#checkAdminConnection()
     * /
    @Override
    public void checkAdminConnection() throws NotConnectedException
    {
        // TO DO
    }*/

    /* (non-Javadoc)
     * @see com.googlecode.bipol.war.session.IBipolSession#getUserid()
     */
    @Override
    public int getUserid()
    {
        return this.userId;
    }

    /* (non-Javadoc)
     * @see com.googlecode.bipol.war.session.IBipolSession#setUserid(int, java.lang.String)
     */
    @Override
    public void setUserid(final int userid, final String username)
    {
        if( userid == 0 ) {
            reset();
            }
        else {
            this.userId = userid;
            this.userName = username.toString(); // check username not null
        }
    }

    /* (non-Javadoc)
     * @see com.googlecode.bipol.war.session.IBipolSession#getUsername()
     */
    @Override
    public String getUsername()
    {
        return this.userName;
    }

    /**
     * TODO: improve
     * @param request ServletRequest to use to identify user idlocal
     * @return
     */
    public static Locale getUserLocale( final ServletRequest request )
    {
        Locale locale = request.getLocale();

        if( locale != null ) {
            // TODO: check if this local is valid for DB
            // Try to find best Locale for user
            return locale;
            }

        return Locale.FRENCH; // TODO: well, something configure on server will be better
    }

    /* (non-Javadoc)
     * @see com.googlecode.bipol.war.session.IBipolSession#getLocale()
     */
    @Override
    public Locale getLocale()
    {
       return this.locale;
    }

    /* (non-Javadoc)
     * @see com.googlecode.bipol.war.session.IBipolSession#setLocale(java.util.Locale)
     */
    @Override
    public void setLocale( final Locale locale )
    {
        this.locale = locale;
    }

    /* (non-Javadoc)
     * @see com.googlecode.bipol.war.session.IBipolSession#getIdlocal()
     */
    @Override
    public String getIdlocal()
    {
       return this.locale.getLanguage();
    }

    /* (non-Javadoc)
     * @see com.googlecode.bipol.war.session.IBipolSession#setIdlocal(java.lang.String)
     */
    @Override
    public void setIdlocal( final String idLocal )
    {
        setLocale( new Locale( idLocal ) );
    }

    /* (non-Javadoc)
     * @see com.googlecode.bipol.war.session.IBipolSession#getLoginTimestamp()
     */
    @Override
    public Timestamp getLoginTimestamp()
    {
        return this.loginTimestamp;
    }

    /* (non-Javadoc)
     * @see com.googlecode.bipol.war.session.IBipolSession#getLoginTime()
     */
    @Override
    public long getLoginTime()
    {
        return this.loginTimestamp.getTime();
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    /* (non-Javadoc)
     * @see com.googlecode.bipol.war.session.IBipolSession#toString()
     */
    @Override
    public String toString()
    {
        StringBuilder builder = new StringBuilder();
        builder.append( "BiPolSession [transient_DataSource=" );
       // builder.append( transient_DataSource );
        builder.append( ", userId=" );
        builder.append( userId );
        builder.append( ", userName=" );
        builder.append( userName );
        builder.append( ", locale=" );
        builder.append( locale );
        builder.append( ", loginTimestamp=" );
        builder.append( loginTimestamp );
        builder.append( "]" );
        return builder.toString();
    }

    /**
     * DEBUG ONLY
     * @param session current HttpSession
     * @return current JSONRPCBridge (create one if not found on session)
     */
    public static JSONRPCBridge getJSONRPCBridge(HttpSession session)
    {
        JSONRPCBridge json_bridge = (JSONRPCBridge)session.getAttribute( JSONRPCBridgeNAME );

        if( json_bridge == null ) {
            logger.warn( "JSONRPCBridge not found, create a new one." );

            json_bridge = new JSONRPCBridge();
            session.setAttribute(JSONRPCBridgeNAME, json_bridge);
            }

        return json_bridge;
    }

    /**
     *
     * @param httpSession
     * @return
     */
    public static _IBiPolSession getSession(HttpSession session)
    {
        /*
        JSONRPCBridge json_bridge = getJSONRPCBridge( session );
        */

        // TODO: recuperer la valeur sur json_bridge

        return null;
    }

    /**
     * Returns current IBiPolSession
     * @param request current HttpServletRequest object
     * @return current IBiPolSession if exist, null otherwise
     */
    public static _IBiPolSession getSession(HttpServletRequest request)
    {
        return getSession( request.getSession() );
    }
/*
    public static void test( HttpSession session )
    {
        JSONRPCBridge b = getJSONRPCBridge( session );
    }
*/
}
/*
class text extends JSONRPCBridge
{
    private static final long serialVersionUID = 1L;
    @Override
    public JSONRPCResult call(Object[] arg0, JSONObject arg1) {
        return super.call(arg0, arg1);
    }
    @Override
    public void enableReferences() throws Exception {
        super.enableReferences();
    }
    @Override
    public JSONSerializer getSerializer() {
        return super.getSerializer();
    }
    @Override
    protected boolean isCallableReference(Class clazz) {
        return super.isCallableReference(clazz);
    }
    @Override
    protected boolean isDebug() {
        return super.isDebug();
    }
    @Override
    protected boolean isReference(Class clazz) {
        return super.isReference(clazz);
    }
    @Override
    public Class lookupClass(String name) throws Exception {
        return super.lookupClass(name);
    }
    @Override
    public Object lookupObject(String arg0) throws Exception {
        return super.lookupObject(arg0);
    }
    @Override
    public void registerCallableReference(Class clazz) throws Exception {
        super.registerCallableReference(clazz);
    }
    @Override
    public void registerCallback(InvocationCallback callback,
            Class contextInterface) {
        super.registerCallback(callback, contextInterface);
    }
    @Override
    public void registerClass(String arg0, Class arg1) throws Exception {
        super.registerClass(arg0, arg1);
    }
    @Override
    public void registerObject(Object key, Object o, Class interfaceClass) {
        super.registerObject(key, o, interfaceClass);
    }
    @Override
    public void registerObject(Object key, Object o) {
        super.registerObject(key, o);
    }
    @Override
    public void registerReference(Class clazz) throws Exception {
        super.registerReference(clazz);
    }
    @Override
    public void registerSerializer(Serializer s) throws Exception {
        super.registerSerializer(s);
    }
    @Override
    public void setDebug(boolean debug) {
        super.setDebug(debug);
    }
    @Override
    public void setSerializer(JSONSerializer ser) {
        super.setSerializer(ser);
    }
    @Override
    public void unregisterCallback(InvocationCallback callback,
            Class contextInterface) {
        super.unregisterCallback(callback, contextInterface);
    }
    @Override
    public void unregisterClass(String name) throws Exception {
        super.unregisterClass(name);
    }
    @Override
    public void unregisterObject(Object arg0) {
        super.unregisterObject(arg0);
    }

}
*/
